export class FollowMe {
    /**
     * 存放各个引导节点的配置
     * target: 焦点
     * title: 提示标题
     * content: 提示内容，可以是string/function/vue-component
     * width: 宽度
     * height: 高度
     * position: 位置 top|top-left|top-right|right|right-top|right-bottom|bottom|bottom-left|bottom-right|left|left-top|left-right
     * hideClose: 隐藏右上角的close图标
     * hideBottom: 隐藏底部按钮
     */
    options = [];

    /**
     * 当前展示的引导节点，对应options数组的下标
     */
    showIndex = -1;
    constructor(options) {
        this.options = options;
    }
    setup() {
        this.showIndex = -1;
        this.next();
    }
    next() {
        this.showIndex = this.showIndex + 1;

        // 隐藏所有引导元素
        _hideAll();

        // 判断是否已经展示完全部的引导节点
        if (this.showIndex >= this.options.length) {
            return;
        }
        const option = this.options[this.showIndex];
        _showNodeTip(option)
    }
}

export function hideAll() {
    _hideAll();
}



function _showNodeTip(option) {
    _addMask();
    const focusEl = _createFocus(option.target);
    _appendChild(focusEl);
    const messageEl = _createMessage(focusEl, option);
    _appendChild(messageEl);
    _addMessageBoxContent(option);
    _bindEvent()
}

function _bindEvent() {
    const closeEl = _getElById(_elementIdMap.closeBtn);
    closeEl && closeEl.addEventListener("click", () => {
        _hideAll();
    })
    const bottomBtnEl = _getElById(_elementIdMap.bottomBtn);
    bottomBtnEl && bottomBtnEl.addEventListener("click", () => {
        _hideAll();
    })
}

function _addMessageBoxContent(option) {
    const contentEl = _getElById(_elementIdMap.messageBoxContent);
    if (_isNull(option.content)) {
        return;
    }
    if (typeof option.content === "string") {
        contentEl.innerText = option.content;
    }
    if (typeof option.content === "object") {
        const el = _createEl("div");
        contentEl.appendChild(el);
        option.content.$mount(el);
    }
}

function _isNull(val) {
    if (val === null || val === undefined || val === "") {
        return true;
    }
    return false;
}

function _createMessage(focusEl, option) {
    const messageEl = _createEl("div");
    // 复制focus样式
    messageEl.style.width = focusEl.style.width;
    messageEl.style.height = focusEl.style.height;
    messageEl.style.top = focusEl.style.top;
    messageEl.style.left = focusEl.style.left;
    _addClass(messageEl, "followme-message");
    messageEl.id = _elementIdMap.message;
    // 添加messageBox
    const messageBoxEl = _createEl("div");
    messageBoxEl.id = _elementIdMap.messageBox;
    _addClass(messageBoxEl, "followme-message-box");
    const position = option.position || "bottom-left";
    _addClass(messageBoxEl, `followme-positon-${position}`)
    if (option.width) {
        messageBoxEl.style.width = option.width;
    }
    if (option.height) {
        messageBoxEl.style.height = option.height;
    }
    // 添加箭头
    const arrowEl = _createEl("div");
    _addClass(arrowEl, "followme-message-box_arrow")
    _appendChild(arrowEl, messageBoxEl);
    _appendChild(messageBoxEl, messageEl);
    // 添加messageBoxHeader
    if (!option.hideClose || option.title) {
        _addMessageBoxHeader(messageBoxEl, option);
    }
    // 添加messageBoxContent
    const messageBoxContentEl = _createEl("div");
    _addClass(messageBoxContentEl, "followme-message-box_content")
    messageBoxContentEl.id = _elementIdMap.messageBoxContent;
    _appendChild(messageBoxContentEl, messageBoxEl);
    // 添加底部按钮
    if(!option.hideBottom) {
        _addBottomButton(messageBoxEl);
    }
    messageBoxEl.style.opacity = "0";
    setTimeout(() => {
        _setOffsetPosition(messageEl, messageBoxEl, position);
        messageBoxEl.style.opacity = "1";
    }, 0);
    return messageEl;
}

function _addBottomButton(messageBoxEl) {
    const bottomEl = _createEl("div");
    bottomEl.innerHTML = `
        <div class="followme-message-bottom">
            <button id="${_elementIdMap.bottomBtn}">我知道了</button>
        </div>
    `
    _appendChild(bottomEl, messageBoxEl);
}

function _addMessageBoxHeader(messageBoxEl, option) {
    const headerEl = _createEl("div");
    headerEl.innerHTML = `
    <div class="followme-message-box_header">
        <span>${option.title || ""}</span>
        <svg class="icon" aria-hidden="true" id="${_elementIdMap.closeBtn}">
            <use xlink:href="#icon-close"></use>
        </svg>
    </div>
    `
    _appendChild(headerEl, messageBoxEl);
}

function _createFocus(target) {
    const targetEl = _getElById(target);
    const foucsEl = _createEl("div");
    foucsEl.style.width = `${targetEl.offsetWidth}px`;
    foucsEl.style.height = `${targetEl.offsetHeight}px`;
    foucsEl.style.top = `${targetEl.offsetTop - 4}px`;
    foucsEl.style.left = `${targetEl.offsetLeft - 4}px`;
    _addClass(foucsEl, "followme-target");
    foucsEl.id = _elementIdMap.focus;
    return foucsEl;
}

function _getElById(id) {
    return document.getElementById(id);
}

function _removeEl(el) {
    if (el) {
        document.body.removeChild(el);
    }
}

function _createEl(tabName) {
    return document.createElement(tabName);
}

function _appendChild(el, parent) {
    const body = parent || document.body;
    body.appendChild(el);
}

function _addClass(el, className) {
    el.classList.add(className);
}

const _elementIdMap = {
    mask: "followmeMask",
    focus: "followmeFocus",
    message: "followmeMessage",
    messageBox: "followmeMessageBox",
    closeBtn: "followmeClose",
    messageBoxContent: "followmeMessageBoxContent",
    bottomBtn: "followMeBottomBtn"
}

function _hideAll() {
    for (const key of Object.keys(_elementIdMap)) {
        const el = _getElById(_elementIdMap[key]);
        _removeEl(el);
    }
}

function _addMask() {
    const mask = _createEl("div");
    _addClass(mask, "followme-mask")
    mask.id = _elementIdMap.mask;
    _appendChild(mask)
}
function _setOffsetPosition(target, poper, position) {
    if (["bottom", "bottom-left", "bottom-right"].indexOf(position) !== -1) {
        poper.style.top = `calc(100% + 12px)`;
    }
    if (["top", "top-left", "top-right"].indexOf(position) !== -1) {
        poper.style.bottom = `calc(100% + 12px)`;
    }
    if (["bottom-left", "top-left"].indexOf(position) !== -1) {
        poper.style.left = "-1px"
    }
    if (["bottom-right", "top-right"].indexOf(position) !== -1) {
        poper.style.right = "1px"
    }
    if (["bottom", "top"].indexOf(position) !== -1) {
        poper.style.left = -(poper.offsetWidth / 2 - target.offsetWidth / 2) + "px"
    }
    if (["left", "left-top", "left-bottom"].indexOf(position) !== -1) {
        poper.style.right = `calc(100% + 12px)`;
    }
    if (["right", "right-top", "right-bottom"].indexOf(position) !== -1) {
        poper.style.left = `calc(100% + 12px)`;
    }
    if (["left-top", "right-top"].indexOf(position) !== -1) {
        poper.style.top = `-1px`;
    }
    if (["left-bottom", "right-bottom"].indexOf(position) !== -1) {
        poper.style.bottom = `-1px`;
    }
    if (["left", "right"].indexOf(position) !== -1) {
        poper.style.top = -(poper.offsetHeight / 2 - target.offsetHeight / 2) + "px"
    }
}